/*********************************************************
*Copyright (c) 2009 Rob Groves. All Rights in Pw
*@des: seesion网络链接
*@name: seesion
*@author: zhognsx
*@time: 2015-11-16
*********************************************************/

#ifndef __SESSION_H__
#define __SESSION_H__

#include <boost/asio.hpp>
#include <boost/bind.hpp>  
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp> 
#include <boost/enable_shared_from_this.hpp>
#include <boost/detail/atomic_count.hpp>
#include "message.h"

//本地回调函数
//typedef boost::function<void(boost::system::error_code ec)> callback_t;
//解析MSG头数据, 并返回MSG数据长度; 若buf长满足body数据长, 处理MSG
//msg 
class session;

typedef boost::shared_ptr<session> session_ptr;
typedef boost::shared_ptr<message> message_ptr;

typedef boost::function<void(session_ptr&, message_ptr&) > Read_Msg_CallBack;

typedef boost::function<void(int)> Close_Conn_CallBack;

//简易session
class session : public boost::noncopyable,
	public boost::enable_shared_from_this<session>
{
public:
	session(boost::asio::io_service& ios);
	virtual ~session();

	boost::asio::ip::tcp::socket& socket();
	//
	void start();
	//异步关闭 //异步写
	void async_close();
	void write(const char* data, int length);
	void async_write(boost::shared_ptr<message> msg);
	//设置地址信息
	void setaddress(std::string ip, short port);

	//判断是否已超时
	bool is_timeout();
	inline void set_op_time(){ std::time(&m_last_op_time); }
	inline std::string geterrstr() { return errstr; }
	inline std::string get_addr_ip() { return address; }
	inline UINT32 get_id() { return m_id; }
	inline int get_sta() { return state; }
	inline void update_state(int sta) { state = sta; }

	std::string get_client_info();
	//
	inline void RegisterReadMsgCallBack(Read_Msg_CallBack rc) { read_msg_callback = rc; }
	//注册关闭连接回调
	inline void RegisterCloseConnCallBack(Close_Conn_CallBack ccc) { close_conn_callback = ccc; }
private:
	//处理数据报头 
	void handle_read_header(const boost::system::error_code& error, int bytes_);
	//处理数据包数据
	void handle_read_msg(const boost::system::error_code& error, int bytes_);
	//第一个消息单独处理，剩下的才更好操作 
	void handle_write(const boost::system::error_code& error);
	//
	void handle_close();
	void do_write(boost::shared_ptr<message> msg);
private:
	int state; //标识此session 在server中链接情况

	static boost::detail::atomic_count m_last_id;
	//开始连接时间
	std::time_t m_last_op_time;
	//
	std::string address;
	short port;
	UINT32 m_id;

	//错误信息
	std::string errstr;

	boost::asio::io_service& io_service_;
	boost::asio::ip::tcp::socket socket_;

	//临时存放数据
	boost::shared_ptr<message> read_buf_;
	std::list<boost::shared_ptr<message>> write_bufs_;   

	//读数据回调
	Read_Msg_CallBack read_msg_callback;
	Close_Conn_CallBack close_conn_callback;
	//
	//内存池 分配器shared指针
	//boost::shared_ptr<boost::pool<> > pool;
private:
	boost::asio::deadline_timer m_timer; //定时器
};

#endif //__SESSION_H__